#ifndef _H_I_PROTOCOL_END_POINT_H_
#define _H_I_PROTOCOL_END_POINT_H_

#include "../typedefine.h"
#include "ProtocolDelegate.h"
#include "SProtocolEndPoint.h"
#include "../VectorDefine.h"

namespace QWER
{
	QCLASS CProtocolSocketContainer;
	QCLASS IRunner;
	QINTERFACE IProtocolWrapper;
	QCLASS IPtc;

	QDLL_EXPORT QCLASS IProtocolSocket QABSTRACT
	{
	public:
#ifndef _USING_CLI
		virtual ~IProtocolSocket(){}
#endif
        virtual void OnUnRegister() = 0;
        virtual UINT8 GetPeerNodeType() QCONST_FUNC = 0;
        virtual SProtocolAddress GetPeerAddress() QCONST_FUNC = 0;
		virtual void SendPtc(CONST_REF(SProtocolEndPoint) rsSrcEndPoint, CONST_REF(SProtocolEndPoint) rsDstEndPoint, CONST_PTR_OR_REF(IPtc) roProtocol/*, CONST_PTR_OR_REF(DOnSendProtocol) ronSendProtocol*/) = 0;
		virtual void SendRpcArg(CONST_REF(SProtocolEndPoint) rsSrcEndPoint, CONST_REF(SProtocolEndPoint) rsDstEndPoint, UINT64 qwRpcUID, CONST_PTR_OR_REF(IRpcArg) roProtocol/*, CONST_PTR_OR_REF(DOnSendProtocol) ronSendProtocol*/) = 0;
		virtual void SendRpcRet(CONST_REF(SProtocolEndPoint) rsSrcEndPoint, CONST_REF(SProtocolEndPoint) rsDstEndPoint, UINT64 qwRpcUID, CONST_PTR_OR_REF(IRpcRet) roProtocol/*, CONST_PTR_OR_REF(DOnSendProtocol) ronSendProtocol*/) = 0;
		virtual BOOLN SendProtocol(CONST_REF(SProtocolEndPoint) rsSrcEndPoint, CONST_REF(SProtocolEndPoint) rsDstEndPoint, PTR_OR_REF(IProtocolWrapper) roProtocolWrapper) = 0;
		virtual BOOLN IsKnownType(CONST_PTR_OR_REF(IProtocolWrapper) roProtocolWrapper) = 0;
		UINT32 GetPort() QCONST_FUNC;
		IProtocolSocket(CONST_PTR_OR_REF(DOnRecvedProtocol) ronRecvedProtocol)
		{
			m_onRecvedProtocol = ronRecvedProtocol;
		}
		inline BOOLN IsOpened() QCONST_FUNC { return m_poContainer != NULL_PTR; }
	protected:
		CONST_PTR_OR_REF(DOnRecvedProtocol) _GetRecvedCallback() QCONST_FUNC
		{
			return m_onRecvedProtocol;
		}
		UINT8 _GetLocalNodeType() QCONST_FUNC
		{
			return m_btLocalNodeType;
		}
		CONST_REF(SProtocolAddress) _GetLocalAddress() QCONST_FUNC
		{
			return m_sLocalAddress;
		}
		PTR(IProtocolHelper) _GetProtocolHelper() QCONST_FUNC
		{
			return m_poProtocolHelper;
		}

#ifdef _USING_CLI
	internal:
#else
	private:
		friend class CProtocolServiceResolver;
		friend class CProtocolSocketContainer;
#endif
		void _SetContainer(PTR(CProtocolSocketContainer) poContainer)
		{
			m_poContainer = poContainer;
		}
		PTR(CProtocolSocketContainer) _GetContainer()
		{
			return m_poContainer;
		}
#ifndef _USING_CLI
		CONST_PTR(CProtocolSocketContainer) _GetContainer() QCONST_FUNC
		{
			return m_poContainer;
		}
#endif
		void _RemoveNodeTypeRouter(UINT8 btNodeType);
		void _SetNodeTypeRouter(UINT8 btNodeType, CONST_REF(SProtocolEndPoint) sEndPoint);
		BOOLN _GetNodeTypeRouter(UINT8 btNodeType, REF(SProtocolEndPoint) rsEndPoint) QCONST_FUNC;
		void _Init(UINT8 btLocalNodeType, CONST_REF(SProtocolAddress) rsLocalAddress, PTR_OR_REF(IProtocolHelper) poProtocolHelper);

	private:
		PTR_OR_VAL(DOnRecvedProtocol) m_onRecvedProtocol;
		PTR(CProtocolSocketContainer) m_poContainer = NULL_PTR;
		CVector(SProtocolEndPoint) m_oNodeTypeToEndPoint;
		UINT8 m_btLocalNodeType = 0;
		SProtocolAddress m_sLocalAddress;
		PTR(IProtocolHelper) m_poProtocolHelper = NULL_PTR;
	};
}

#endif
